package com.coocaa.ops.admin.v1.auth.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.coocaa.ops.admin.base.language.CommonLanguageProperties;
import com.coocaa.ops.admin.v1.auth.sys.biz.ISysRoleBiz;
import com.coocaa.ops.admin.v1.auth.sys.biz.ISysUserBiz;
import com.coocaa.ops.admin.v1.auth.sys.biz.ISysUserProfessionGroupRlsBiz;
import com.coocaa.ops.admin.v1.auth.sys.biz.ISysUserRoleBiz;
import com.coocaa.ops.admin.v1.auth.sys.exception.SysUserException;
import com.coocaa.ops.admin.v1.auth.sys.service.ISysUserService;
import com.coocaa.ops.admin.v1.auth.sys.model.query.SysUserModel;
import com.coocaa.ops.admin.v1.auth.sys.util.SysUserValidator;
import com.coocaa.ops.admin.v1.dict.biz.IDictInfoBiz;
import com.coocaa.ops.common.core.base.model.PageResultModel;
import com.coocaa.ops.common.core.base.model.R;
import com.coocaa.ops.common.core.base.util.PageQueryUtil;
import com.coocaa.ops.common.core.biz.auth.entity.SysRoleEntity;
import com.coocaa.ops.common.core.biz.auth.entity.SysUserEntity;
import com.coocaa.ops.common.core.biz.auth.entity.SysUserRoleEntity;
import com.coocaa.ops.common.core.biz.dict.entity.DictInfoEntity;
import com.coocaa.ops.common.tool.date.DateUtil;
import com.coocaa.ops.common.tool.math.RandomUtil;
import com.coocaa.ops.common.tool.md5.MD5Util;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author bijiahao
 * @date : 2019/3/12.
 * @description: 系统用户 service 实现
 */
@Service
public class SysUserServiceImpl implements ISysUserService {
    @Autowired
    private ISysUserBiz sysUserBiz;
    @Autowired
    private ISysUserProfessionGroupRlsBiz sysUserProfessionGroupRlsBiz;
    @Autowired
    private IDictInfoBiz dictInfoBiz;
    @Autowired
    private ISysRoleBiz sysRoleBiz;
    @Autowired
    private ISysUserRoleBiz sysUserRoleBiz;
    private static CommonLanguageProperties commonLanguageProperties;

    @Override
    public Map getNotRolesByUserId(Integer userId) {
        List<SysRoleEntity> notRoles = sysRoleBiz.getMapper().listNotRoleByUserId(userId);
        return R.ok(notRoles);
    }

    @Override
    public Map getRolesByUserId(Integer userId) {
        List<SysRoleEntity> roles = sysRoleBiz.getMapper().listRoleByUserId(userId);
        return R.ok(roles);
    }

    @Override
    public Map getDictCheckedByUserId(Integer userId) {
        List<Integer> dicts = listUserBusinessType(userId);
        return R.ok().data(dicts);
    }

    @Override
    public void saveUserRoles(Integer[] roleIds, Integer userId) {
        List<SysUserRoleEntity> entitys = new ArrayList(roleIds == null ? 0 : roleIds.length);
        if (ArrayUtils.isNotEmpty(roleIds)) {
            for (Integer roleId : roleIds) {
                SysUserRoleEntity entity = new SysUserRoleEntity();
                entity.setUserId(userId);
                entity.setRoleId(roleId);
                entitys.add(entity);
            }
        }
        sysUserRoleBiz.saveBatch(userId, entitys);
    }

    @Override
    public void saveProfession(List<Integer> dicts, Integer userId) {
        sysUserProfessionGroupRlsBiz.saveUserProfession(dicts, userId);
    }

    @Override
    public Map updatePassword(String oldPassword, SysUserEntity user, String newPassword, String newPassword2) throws Exception {
        if (StringUtils.isNotBlank(oldPassword)) {
            if (StringUtils.isNotBlank(newPassword) && newPassword.equals(newPassword2)) {
                if (user.getLoginPwd().equals(MD5Util.md5(MD5Util.md5(oldPassword + user.getSalt())))) {
                    sysUserBiz.updatePassword(oldPassword, user, newPassword);
                    return R.ok().msg("Modified successfully!");
                } else {
                    return R.fail("The old password is incorrectly entered!");
                }
            } else {
                return R.fail("The new password is entered incorrectly!");
            }
        } else {
            return R.fail("The old password can not be empty!");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SysUserEntity entity, Integer userId) throws Exception {
        SysUserValidator.valid(entity);
        if (entity.getId() == null) {
            checkDuplicateName(entity, true);
            String salt = RandomUtil.getNum(6);
            entity.setSalt(salt);
            entity.setLoginPwd(MD5Util.md5(MD5Util.md5(entity.getLoginPwd() + salt)));
            entity.setLoginCount(0);
            entity.setSuperAdmin(0);
            entity.setCreatedDate(DateUtil.getCurDate());
            sysUserBiz.add(entity);
            //保存 业务权限信息
            sysUserProfessionGroupRlsBiz.saveUserProfession(entity.getDicts(), entity.getId());
        } else {
            checkDuplicateName(entity, false);
            if (StringUtils.isNotBlank(entity.getLoginPwd())) {
                String salt = RandomUtil.getNum(6);
                entity.setSalt(salt);
                entity.setLoginPwd(MD5Util.md5(MD5Util.md5(entity.getLoginPwd() + salt)));
            }
            entity.setLastUpdateDate(DateUtil.getCurDate());
            sysUserBiz.updateById(entity);
            //保存 业务权限信息
            sysUserProfessionGroupRlsBiz.saveUserProfession(entity.getDicts(), entity.getId());
        }
    }

    @Override
    public SysUserEntity getDetailInfo(Integer id) {
        SysUserEntity user = sysUserBiz.queryById(id);
        Assert.notNull(user, "user info "+commonLanguageProperties.getNotNull());
        user.setId(user.getId());
        //获取已经选择的业务组
        user.setDicts(listUserBusinessType(user.getId()));
        //密码和盐值不能给前端
        user.setLoginPwd(null);
        user.setSalt(null);
        return user;
    }

    @Override
    public Map<String, Object> getPageResult(SysUserModel model) {
        Map<String, Object> params = PageQueryUtil.getFilterMap(model);
        PageResultModel<SysUserEntity> pageResult = sysUserBiz.getCommonPageList(params, false);
        return R.ok(pageResult);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map deleteBatch(Integer[] ids, SysUserEntity user) {
        String result = this.deleteBatch(ids, user.getId());
        if (R.SUCCESS.equals(result)) {
            return R.ok().msg(commonLanguageProperties.getDeleteSuccess());
        } else {
            return R.fail(result);
        }
    }

    @Autowired
    public void setCommonLanguageProperties(CommonLanguageProperties commonLanguageProperties) {
        SysUserServiceImpl.commonLanguageProperties = commonLanguageProperties;
    }
    /*************** ===私有方法=== ********************* ===start=== ***************************************/
    /**
     * 处理批量删除
     *
     * @param ids
     * @param userId
     * @return
     */
    private String deleteBatch(Integer[] ids, Integer userId) {
        if (ArrayUtils.isNotEmpty(ids)) {
            UpdateWrapper<SysUserEntity> wrapper = new UpdateWrapper<>();
            wrapper.in("id", ids);
            SysUserEntity update = new SysUserEntity();
            update.setDisabled(2);
            update.setLastUpdateDate(DateUtil.getCurDate());
            sysUserBiz.getMapper().update(update, wrapper);
        }
        return R.SUCCESS;
    }

    /**
     * 获取用户的业务分类
     *
     * @param userId
     * @return
     */
    private List<Integer> listUserBusinessType(Integer userId) {
        List<DictInfoEntity> types = dictInfoBiz.listUserBusinessType(userId);
        if (CollectionUtils.isNotEmpty(types)) {
            //存储业务组id
            List<Integer> dict = new ArrayList<>(types.size());
            for (DictInfoEntity type : types) {
                dict.add(type.getId());
            }
            return dict;
        }
        return Collections.emptyList();
    }

    /**
     * 校验是否有重复的登陆名或邮箱
     *
     * @param entity
     * @param isAdding 是否新增用户或修改用户
     * @throws SysUserException
     */
    private void checkDuplicateName(SysUserEntity entity, boolean isAdding) throws SysUserException {
        if (doesLoginNameExist(entity.getLoginName(), entity.getId(), isAdding)) {
            throw new SysUserException("The same login name exists");
        }
        if (doesEmailExist(entity.getEmail(), entity.getId(), isAdding)) {
            throw new SysUserException("Same email exists");
        }
    }

    private boolean doesLoginNameExist(String loginName, Integer userId, boolean isAdding) {
        SysUserEntity entity = sysUserBiz.getUserByLoginName(loginName);
        if (entity == null) {
            return false;
        } else {
            //如果存在相同登录名，且是新增用户，则表示存在重名
            //  如果是修改用户，需校验查出的用户是否是本用户，不是则表示重名
            return isAdding ? true : !userId.equals(entity.getId());
        }
    }

    private boolean doesEmailExist(String email, Integer userId, boolean isAdding) {
        SysUserEntity entity = sysUserBiz.getUserByEmail(email);
        if (entity == null) {
            return false;
        } else {
            //如果存在相同邮箱，且是新增用户，则表示存在重复邮箱
            //  如果是修改用户，需校验查出的用户是否是本用户，不是则表示重复邮箱
            return isAdding ? true : !userId.equals(entity.getId());
        }
    }
}
